﻿namespace Sai.Core.Reporting
{
	using System.IO;
	using System.Text;
	using System.Xml;
	using System.Xml.XPath;
	using System.Xml.Xsl;

	/// <summary>
	/// Transforms xml content into another format using an embedded xslt.
	/// </summary>
    public class XmlTransformer : ITextTransformer
	{
        private XslCompiledTransform _xslTransform;

		public XmlTransformer(string xsltContent)
		{
			this.XsltContent = xsltContent;
		}

		private string XsltContent { get; set; }

        private XslCompiledTransform XslTransform
        {
            get
            {
                if (this._xslTransform == null)
                {
                    this._xslTransform = new XslCompiledTransform();
                    
                    using (XmlTextReader transformReader = new XmlTextReader(new StringReader(this.XsltContent)))
                    {
                        this._xslTransform.Load(transformReader);
                    }
                }

                return this._xslTransform;
            }
        }

		/// <summary>
		/// Transform the xml content into a formatted string.
		/// </summary>
		/// <param name="xmlContent">The text xml content</param>
		/// <returns>The transformed text</returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")]
        public string Transform(string xmlContent)
		{
            string output = string.Empty;

            try
            {
                XPathDocument doc = new XPathDocument(new StringReader(xmlContent));

                XmlWriterSettings settings = new XmlWriterSettings();
                settings.Encoding = Encoding.UTF8;
                settings.Indent = true;
                settings.IndentChars = "    ";
                settings.OmitXmlDeclaration = true;
                settings.ConformanceLevel = ConformanceLevel.Fragment;

                using (StringWriter sw = new StringWriter())
                {
                    using (XmlWriter writer = XmlWriter.Create(sw, settings))
                    {
                        this.XslTransform.Transform(doc, null, writer);
                        output = sw.ToString();
                    }
                }
            }
            catch (XmlException ex)
            {
                output = ex.ToString() + System.Environment.NewLine + xmlContent;
            }

            return output;
		}
	}
}
